package com.xzy.common.util;

import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;


/**
 * TOKEN工具类
 *
 * @author xzy.xiao
 * @date 2023/4/2  16:21
 */
public class TokenUtils {
    /**
     * 用于签名的秘钥，可以根据需要修改
     */
    private static final String SECRET_KEY = "zLVVwXq7Oo0kQRkpE49GTgnkuwGNT4rb661rgANwY3c=";

    /**
     * 过期时间，单位为秒，可以根据需要修改
     */
    private static final long EXPIRATION_TIME = 3600;

    /**
     * 将对象转换为 JSON 字符串，并将其封装在 TOKEN 中
     *
     * @param subject 对象
     * @return TOKEN
     */
    public static String generateToken(Object subject) {
        long now = System.currentTimeMillis();
        Date nowDate = new Date(now);
        Date expirationDate = new Date(now + EXPIRATION_TIME * 1000);
        JwtBuilder builder = Jwts.builder()
                .setSubject(JSON.toJSONString(subject))
                .setIssuedAt(nowDate)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY);
        return builder.compact();
    }

    /**
     * 验证 TOKEN 是否有效
     *
     * @param token TOKEN
     * @return true - TOKEN 有效，false - TOKEN 无效
     */
    public static boolean validateToken(String token) {
        if (token == null || "".equals(token)) {
            return false;
        }

        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 验证 TOKEN 是否有效，并解析其中的Subject
     *
     * @param token        TOKEN
     * @param subjectClazz subject 类型
     * @return null - TOKEN 无效
     */
    public static <T> T validateToken(String token, Class<T> subjectClazz) {
        if (token == null || "".equals(token)) {
            return null;
        }

        try {
            Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
            String subjectJson = claims.getSubject();
            return JSON.parseObject(subjectJson, subjectClazz);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 解析 TOKEN 获取封装的对象
     *
     * @param token TOKEN
     * @return 封装的对象
     */
    public static <T> T parseToken(String token, Class<T> clazz) {
        Claims claims = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
        String subjectJson = claims.getSubject();
        return JSON.parseObject(subjectJson, clazz);
    }

    public static void main(String[] args) {

        // 原始数据
        Date originData = new Date();

        // 封装TOKEN
        String token = TokenUtils.generateToken(originData);
        System.out.println(token);

        // 校验TOKEN
        System.out.println(TokenUtils.validateToken(token));

        // 解析TOKEN
        Date parseData = TokenUtils.parseToken(token, Date.class);
        System.out.println(parseData);

    }
}
